package org.esti.controller;

import org.esti.model.AppraisalTask;
import org.esti.model.Interview;
import org.esti.model.KnowledgeField;
import org.esti.model.User;
import org.esti.model.utils.InterviewPropertyEditor;
import org.esti.model.utils.InterviewResultPropertyEditor;
import org.esti.model.utils.KnowledgeFieldPropertyEditor;
import org.esti.model.utils.LevelPropertyEditor;
import org.esti.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Artem Loginov (logart)
 */

/**
 * This controller is used for providing mapping between request and view
 * and showing different interview information.
 * For example: is this interview passed or not or date when it happens.
 */

@Controller
public class InterviewController {

    private static final Logger LOGGER = Logger.getLogger(InterviewController.class.getName());

    @Autowired
    private UserService userService;

    @Autowired
    private InterviewService interviewService;

    @Autowired
    private AppraisalTaskService appraisalTaskService;

    @Autowired
    private LevelService levelService;

    @Autowired
    private KnowledgeFieldService knowledgeFieldService;

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(org.esti.model.Interview.class, new InterviewPropertyEditor(interviewService));
        binder.registerCustomEditor(org.esti.model.Level.class, new LevelPropertyEditor(levelService));
        binder.registerCustomEditor(org.esti.model.KnowledgeField.class, new KnowledgeFieldPropertyEditor(knowledgeFieldService));
        binder.registerCustomEditor(org.esti.model.InterviewResult.class, new InterviewResultPropertyEditor(interviewService));
        CustomDateEditor editor = new CustomDateEditor(new SimpleDateFormat("dd/MM/yyyy H:mm"), true);
        binder.registerCustomEditor(Date.class, editor);
    }

    /**
     * Show user passed interviews.
     * This method generate list off all interviews user ever passed on this site
     * and put this list in to model
     *
     * @param login of user whose interview we want to retrieve
     * @param model set of parameters which will be passed to view. In this case all user interviews
     * @return name of view which will be render
     */
    @RequestMapping(value = "/{login}/interviews")
    public String showPastInterviews(@PathVariable String login, Model model) {
        User user = userService.getUserByLogin(login);

        model.addAttribute("user", user);

        List<Interview> interviews = interviewService.getUserInterviews(user.getId());
        model.addAttribute("interviews", interviews);

        return "interviews";
    }

    /**
     * Shows single interview by it's identity in the database
     *
     * @param id    of interview we want to see
     * @param model set of parameters which will be passed to view. In this case single interview
     * @return name of view which will be render
     */
    @RequestMapping(value = "/interviews/{id}")
    public String showInterview(@PathVariable long id, Model model) {

        model.addAttribute("interview", interviewService.getInterview(id));

        model.addAttribute("interviewResults", interviewService.getInterviewResults(id));


        return "interview";
    }

    /**
     * show form to submit user interview result
     * @param login of user which interview will be added
     * @param model set of parameters which will be passed to view.
     * @return view name
     */
    @RequestMapping(value = "/{login}/interviews", params = {"action=edit"}, method = RequestMethod.GET)
    public String showAddUserInterviewForm(@PathVariable String login, Model model) {

        Interview interview = new Interview();
        User user = userService.getUserByLogin(login);
        interview.setLevel(user.getLevel());
        Map<KnowledgeField, List<AppraisalTask>> appraisalTasks = appraisalTaskService.getAppraisalTasksByLevelId(user.getLevel().getId());
        model.addAttribute("appraisalTasks", appraisalTasks);
        model.addAttribute("interview", interview);
        model.addAttribute("user", user);

        return "add_interview";
    }

    /**
     * process adding user interview
     * @param interview which will be saved to DB
     * @param bindingResult binder that provide validation and error reporting if interview has failed fields
     * @param login of user which interview will be added
     * @param model set of parameters which will be passed to view.
     * @return view name
     */
    @RequestMapping(value = "/{login}/interviews", params = {"action=edit"}, method = RequestMethod.POST)
    public String addUserInterview(
            @Valid @ModelAttribute Interview interview,
            BindingResult bindingResult,
            @PathVariable String login,
            Model model) {


        if (bindingResult.hasErrors()) {
            LOGGER.log(Level.INFO, "error till binding interview");
            return "add_interview";
        }

        User user = userService.getUserByLogin(login);
        interview.setUser(user);
        interview.setLevel(user.getLevel());
        interviewService.create(interview);
        return "redirect:/" + login + "/interviews";
    }
}
